﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Drawing;
using System.IO;
using System.Net;
using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;

namespace System {
    /// <summary>
    /// 工具类
    /// </summary>
    public partial class Utils {
        public static T GetObjTranNull<T>(object obj) {
            try {
                if(obj==null) {
                    return (T)System.Convert.ChangeType("",typeof(T));
                } else {
                    if(obj.GetType()==typeof(T))
                        return (T)obj;
                }
                return (T)System.Convert.ChangeType(obj,typeof(T));
            } catch { }
            return default(T);
        }
        public static T Run<T>(Func<T> func) {
            DateTime startTime = DateTime.Now;
            T _obj = default(T);
            try {
                _obj=func();
            } catch(Exception ex) {

            }
            DateTime endTime = DateTime.Now;
            var ts = endTime-startTime;
            Console.WriteLine("运行耗时："+(endTime-startTime).TotalMilliseconds.ToString()+"ms");
            return _obj;
        }
        public static void Run(Action action,int stepTotal = 10000,string description = "") {
            DateTime startTime = DateTime.Now;
            for(int i = 0;i<stepTotal;i++) {
                action();
            }
            DateTime endTime = DateTime.Now;
            var ts = endTime-startTime;
            Console.WriteLine(description+"_运行“"+stepTotal.ToString()+"”次耗时："+(endTime-startTime).TotalMilliseconds.ToString()+"ms");
        }
        #region 唯一订单号生成

        /// <summary>
        /// 唯一订单号生成
        /// </summary>
        /// <returns></returns>
        public static string GenerateOrderNumber() {
            string strDateTimeNumber = DateTime.Now.ToString("yyyyMMddHHmmssffff");
            string strRandomResult = NextRandom(1000,1).ToString("0000");
            return strDateTimeNumber+strRandomResult;
        }
        /// <summary>
        /// 参考：msdn上的RNGCryptoServiceProvider例子
        /// </summary>
        /// <param name="numSeeds"></param>
        /// <param name="length"></param>
        /// <returns></returns>
        private static int NextRandom(int numSeeds,int length) {
            // Create a byte array to hold the random value.
            byte[] randomNumber = new byte[length];
            // Create a new instance of the RNGCryptoServiceProvider.
            RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
            // Fill the array with a random value.
            rng.GetBytes(randomNumber);
            // Convert the byte to an uint value to make the modulus operation easier.
            uint randomResult = 0x0;
            for(int i = 0;i<length;i++) {
                randomResult|=((uint)randomNumber[i]<<((length-1-i)*8));
            }
            return (int)(randomResult%numSeeds)+1;
        }
        static string Seq = "s9LFkgy5RovixI1aOf8UhdY3r4DMplQZJXPqebE0WSjBn7wVzmN2Gc6THCAKut";
        #endregion
        public static string FilterSql(string s) {
            if(string.IsNullOrEmpty(s)) return string.Empty;
            s=s.Trim().ToLower();
            //s = ClearScript(s);
            s=s.Replace("=","");
            s=s.Replace("'","");
            s=s.Replace(";","");
            s=s.Replace(" or ","");
            s=s.Replace("select","");
            s=s.Replace("update","");
            s=s.Replace("insert","");
            s=s.Replace("delete","");
            s=s.Replace("declare","");
            s=s.Replace("exec","");
            s=s.Replace("drop","");
            s=s.Replace("create","");
            s=s.Replace("%","");
            s=s.Replace("--","");
            return s;
        }

        #region GET/POST
        /// <summary>
        /// HttpGet
        /// </summary>
        /// <param name="url"></param>
        /// <returns></returns>
        public static string HttpGet(string url) {
            string retString = string.Empty;
            string errMsg = string.Empty;
            try {
                HttpWebRequest wbRequest = (HttpWebRequest)WebRequest.Create(url);
                wbRequest.Method="GET";
                wbRequest.ContentType="text/html;charset=UTF-8";
                HttpWebResponse wbResponse = (HttpWebResponse)wbRequest.GetResponse();
                using(Stream responseStream = wbResponse.GetResponseStream()) {
                    using(StreamReader sReader = new StreamReader(responseStream,Encoding.GetEncoding("utf-8"))) {
                        retString=sReader.ReadToEnd();
                    }
                }
            } catch(Exception ex) {
                errMsg=errMsg+ex.Message;           
                Async.AsyncRun(delegate {
                    Logger.LogError("HttpGet url:"+url,ex);
                });
            }
            if(AppConfig.Debug) {
                Async.AsyncRun(delegate {
                    Logger.LogTrace("HttpGet url:"+url+" return : "+Environment.NewLine+retString+Environment.NewLine+errMsg);
                    EmailHepler.SendEmail("HttpGet url:"+url,"HttpGet url:"+url+Environment.NewLine+" return : "+Environment.NewLine+retString+Environment.NewLine+errMsg);
                });
            }
            return retString;
        }
        /// <summary>
        /// HttpPost
        /// </summary>
        /// <param name="url"></param>
        /// <param name="paramData">参数 格式"roleId=1&uid=2"</param>
        /// <param name="headerDic">header </param>
        /// <returns></returns>
        public static string HttpPost(string url,IDictionary<string,string> paramData,Dictionary<string,string> headerDic = null) {
            StringBuilder buffer = new StringBuilder();
            StringBuilder errMsg = new StringBuilder();
            HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
            request.ProtocolVersion=HttpVersion.Version10;
            request.Method="POST";
            request.ContentType="application/x-www-form-urlencoded";
            if(headerDic!=null&&headerDic.Count>0) {
                errMsg.AppendLine("request.Headers:");
                foreach(var item in headerDic) {
                    request.Headers.Add(item.Key,item.Value);
                    errMsg.AppendLine(item.Key+"="+item.Value);
                }
            }
            //POST参数拼接     
            if(!(paramData==null||paramData.Count==0)) {
                errMsg.AppendLine("POST参数:");
                int i = 0;
                foreach(string key in paramData.Keys) {
                    if(i>0) {
                        buffer.AppendFormat("&{0}={1}",key,paramData[key]);
                    } else {
                        buffer.AppendFormat("{0}={1}",key,paramData[key]);
                    }
                    errMsg.AppendFormat("{0}={1}",key,paramData[key]).AppendLine();
                    i++;
                }
                byte[] data = Encoding.UTF8.GetBytes(buffer.ToString());
                using(Stream stream = request.GetRequestStream()) {
                    stream.Write(data,0,data.Length);
                }
            }
            string retStr = "";
            HttpWebResponse response = (HttpWebResponse)request.GetResponse();
            using(StreamReader reader = new StreamReader(response.GetResponseStream(),Encoding.UTF8)) {
                retStr= reader.ReadToEnd();
            }
            if(AppConfig.Debug) {
                Async.AsyncRun(delegate {
                    Logger.LogTrace("HttpPost url:"+url+Environment.NewLine+" return : "+Environment.NewLine+retStr+Environment.NewLine+errMsg);
                    EmailHepler.SendEmail("HttpPost url:"+url,"HttpPost url:"+url+Environment.NewLine+" return : "+Environment.NewLine+retStr+Environment.NewLine+errMsg);
                });
            }
            return retStr;
        }
        #endregion
    }
}
